package wk.demo.widget.media;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

import com.luoye.bzijkplayer.R;

import java.lang.ref.WeakReference;
import java.util.Locale;

import tv.danmaku.ijk.media.player.mplayer.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
import tv.danmaku.ijk.media.player.MediaPlayerProxy;
import wk.demo.callback.OnGetRealTimeInfo;
import wk.demo.tool.WkLogTool;

public class InfoHudViewHolder {
    private IMediaPlayer mMediaPlayer;
    private long mLoadCost = 0;
    private long mSeekCost = 0;
    private Context mContext ;
    private OnGetRealTimeInfo onGetRealTimeInfo ;
    private MyHandler myHandler   ;
    private static final int MSG_UPDATE_HUD = 1;

    public InfoHudViewHolder(Context context,  OnGetRealTimeInfo onGetRealTimeInfo ) {
        this.mContext =context ;
        this.onGetRealTimeInfo =onGetRealTimeInfo ;
        myHandler =new MyHandler(this) ;
    }

    private void setRowValue(int id, String value) {
        if(onGetRealTimeInfo!=null){
            String key = mContext.getString(id) ;
            onGetRealTimeInfo.onGetRealTimeMsg(key ,value);
        }
    }

    public void setMediaPlayer(IMediaPlayer mp) {
        mMediaPlayer = mp;
        if (mMediaPlayer != null) {
            myHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500);
        } else {
            myHandler.removeMessages(MSG_UPDATE_HUD);
        }
    }

    private static String formatedDurationMilli(long duration) {
        if (duration >=  1000) {
            return String.format(Locale.US, "%.2f sec", ((float)duration) / 1000);
        } else {
            return String.format(Locale.US, "%d msec", duration);
        }
    }

    private static String formatedSpeed(long bytes,long elapsed_milli) {
        if (elapsed_milli <= 0) {
            return "0 B/s";
        }

        if (bytes <= 0) {
            return "0 B/s";
        }

        float bytes_per_sec = ((float)bytes) * 1000.f /  elapsed_milli;
        if (bytes_per_sec >= 1000 * 1000) {
            return String.format(Locale.US, "%.2f MB/s", ((float)bytes_per_sec) / 1000 / 1000);
        } else if (bytes_per_sec >= 1000) {
            return String.format(Locale.US, "%.1f KB/s", ((float)bytes_per_sec) / 1000);
        } else {
            return String.format(Locale.US, "%d B/s", (long)bytes_per_sec);
        }
    }

    public void updateLoadCost(long time)  {
        mLoadCost = time;
    }

    public void updateSeekCost(long time)  {
        mSeekCost = time;
    }

    private static String formatedSize(long bytes) {
        if (bytes >= 100 * 1000) {
            return String.format(Locale.US, "%.2f MB", ((float)bytes) / 1000 / 1000);
        } else if (bytes >= 100) {
            return String.format(Locale.US, "%.1f KB", ((float)bytes) / 1000);
        } else {
            return String.format(Locale.US, "%d B", bytes);
        }
    }

    private static class MyHandler extends Handler {
        //WeakReference 当GC执行时，无论当前内存是否充足，都会将若引用关联的对象回收掉。
        private final WeakReference<InfoHudViewHolder> weakReference;

        public MyHandler(InfoHudViewHolder controller) {
            weakReference = new WeakReference<>(controller );
        }

        @Override
        public void handleMessage(Message msg) {
            InfoHudViewHolder holder = weakReference.get() ;
            if(holder==null){
                WkLogTool.showLog("holder==null ......");
                return;
            }

            if (msg.what == MSG_UPDATE_HUD) {

                IMediaPlayer player = holder.mMediaPlayer;
                IjkMediaPlayer mp = null;

                if (player == null){
                    return;
                }

                if ( player instanceof IjkMediaPlayer) {
                    mp = (IjkMediaPlayer) player;

                } else if ( player instanceof MediaPlayerProxy) {
                    MediaPlayerProxy proxy = (MediaPlayerProxy)  player;
                    IMediaPlayer internal = proxy.getInternalMediaPlayer();
                    if(internal!=null){
                        if ( internal instanceof IjkMediaPlayer){
                            mp = (IjkMediaPlayer) internal;
                        }
                    }
                }


                if (mp == null){
                    return;
                }

                int vdec = mp.getVideoDecoder();
                switch (vdec) {
                    case IjkMediaPlayer.FFP_PROPV_DECODER_AVCODEC:
                        holder.setRowValue(R.string.vdec, "avcodec");
                        break;
                    case IjkMediaPlayer.FFP_PROPV_DECODER_MEDIACODEC:
                        holder.setRowValue(R.string.vdec, "MediaCodec");
                        break;
                    default:
                        holder.setRowValue(R.string.vdec, "unKnow");
                        break;
                }

                float fpsOutput = mp.getVideoOutputFramesPerSecond();
                float fpsDecode = mp.getVideoDecodeFramesPerSecond();
                holder.setRowValue( R.string.fps, String.format(Locale.US, "%.2f  , %.2f", fpsDecode, fpsOutput));

                long videoCachedDuration = mp.getVideoCachedDuration();
                long audioCachedDuration = mp.getAudioCachedDuration();
                long videoCachedBytes = mp.getVideoCachedBytes();
                long audioCachedBytes = mp.getAudioCachedBytes();
                long tcpSpeed = mp.getTcpSpeed();
                long bitRate = mp.getBitRate();
                long seekLoadDuration = mp.getSeekLoadDuration();

                holder.setRowValue(R.string.v_cache, String.format(Locale.US, "%s, %s", formatedDurationMilli(videoCachedDuration), formatedSize(videoCachedBytes)));
                holder.setRowValue(R.string.a_cache, String.format(Locale.US, "%s, %s", formatedDurationMilli(audioCachedDuration), formatedSize(audioCachedBytes)));
                holder.setRowValue(R.string.load_cost, String.format(Locale.US, "%d ms", holder.mLoadCost));
                holder.setRowValue(R.string.seek_cost, String.format(Locale.US, "%d ms", holder.mSeekCost));
                holder.setRowValue(R.string.seek_load_cost, String.format(Locale.US, "%d ms", seekLoadDuration));
                holder.setRowValue(R.string.tcp_speed, String.format(Locale.US, "%s", formatedSpeed(tcpSpeed, 1000)));
                holder.setRowValue(R.string.bit_rate, String.format(Locale.US, "%.2f kbs", bitRate / 1000f));

                holder.myHandler.removeMessages(MSG_UPDATE_HUD);
                holder.myHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500);
            }
        }
    }











}
